package TuringMachineTests;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import junit.framework.TestCase;

import org.junit.Test;

import TuringMachine.Movement;
import TuringMachine.Parser;
import TuringMachine.TuringMachine;

public class TuringMachineTests extends TestCase {

	@Test
	public void testCase1() {
		// s0,0,s1,1
		TuringMachine tm = new TuringMachine();
		tm.setCurrentState("s0");

		Map<Integer, Movement> s0 = new HashMap<Integer, Movement>();
		s0.put(0, new Movement("1", "s1"));
		tm.getNodes().put("s0", s0);

		tm.execute();

		String tape = "";
		for (int i = tm.getMinPosition(); i <= tm.getMaxPosition(); i++) {
			tape += tm.getTape().get(i);
		}

		assertTrue(tape.equals("1"));
	}

	@Test
	public void testCase2() {
		// s0,0,s1,1
		// s1,1,s2,>
		// s2,0,s3,>

		TuringMachine tm = new TuringMachine();
		tm.setCurrentState("s0");

		Map<Integer, Movement> s0 = new HashMap<Integer, Movement>();
		s0.put(0, new Movement("1", "s1"));
		tm.getNodes().put("s0", s0);

		Map<Integer, Movement> s1 = new HashMap<Integer, Movement>();
		s1.put(1, new Movement(">", "s2"));
		tm.getNodes().put("s1", s1);

		Map<Integer, Movement> s2 = new HashMap<Integer, Movement>();
		s2.put(0, new Movement(">", "s3"));
		tm.getNodes().put("s2", s2);

		tm.execute();

		String tape = "";
		for (int i = tm.getMinPosition(); i <= tm.getMaxPosition(); i++) {
			tape += tm.getTape().get(i);
		}

		assertTrue(tape.equals("100"));
	}

	@Test
	public void testCase3() {
		// s0,0,s1,1
		// s1,1,s2,<
		// s2,0,s3,2
		// s3,2,s3,>
		// a3,1,s3,>

		TuringMachine tm = new TuringMachine();
		tm.getTape().put(0, 0);
		tm.getTape().put(1, 1);
		tm.getTape().put(2, 2);
		tm.setCurrentState("s0");

		Map<Integer, Movement> s0 = new HashMap<Integer, Movement>();
		s0.put(0, new Movement("1", "s1"));
		tm.getNodes().put("s0", s0);

		Map<Integer, Movement> s1 = new HashMap<Integer, Movement>();
		s1.put(1, new Movement("<", "s2"));
		tm.getNodes().put("s1", s1);

		Map<Integer, Movement> s2 = new HashMap<Integer, Movement>();
		s2.put(0, new Movement("2", "s3"));
		tm.getNodes().put("s2", s2);

		Map<Integer, Movement> s3 = new HashMap<Integer, Movement>();
		s3.put(2, new Movement(">", "s3"));
		s3.put(1, new Movement(">", "s3"));
		tm.getNodes().put("s3", s3);

		tm.execute();

		String tape = "";
		for (int i = tm.getMinPosition(); i <= tm.getMaxPosition(); i++) {
			tape += tm.getTape().get(i);
		}

		assertTrue(tape.equals("21120"));
	}

	@Test
	public void testMachine1() {
		TuringMachine tm = new TuringMachine();
		Parser parser = new Parser();
		File file = new File("maquinas/machine1.mt");

		boolean error = true;

		try {
			error = parser.readFile(file, tm);
		} catch (IOException e) {
			System.err.println("Error al abrir el archivo solicitado!");
		}
		
		assertFalse(error);
		
		if (error)
			return;
		
		tm.getTape().put(0, 1);
		tm.getTape().put(1, 1);
		tm.getTape().put(2, 1);

		tm.execute();

		String tape = "";
		for (int i = tm.getMinPosition(); i <= tm.getMaxPosition(); i++) {
			tape += tm.getTape().get(i);
		}

		assertTrue(tape.equals("1110111"));
	}

	@Test
	public void testMachine2() {
	}
	
	@Test
	public void testMachine3() {
		TuringMachine tm = new TuringMachine();
		Parser parser = new Parser();
		File file = new File("maquinas/machine3.mt");

		boolean error = true;

		try {
			error = parser.readFile(file, tm);
		} catch (IOException e) {
			System.err.println("Error al abrir el archivo solicitado!");
		}
		
		assertFalse(error);
		
		if (error)
			return;

		tm.getTape().put(0, 0);
		tm.getTape().put(1, 1);
		tm.getTape().put(2, 2);
		tm.getTape().put(3, 0);
		tm.getTape().put(4, 1);
		tm.getTape().put(5, 2);

		tm.execute();

		String tape = "";
		for (int i = tm.getMinPosition(); i <= tm.getMaxPosition(); i++) {
			tape += tm.getTape().get(i);
		}

		assertTrue(tape.equals("210012"));
	}

	@Test
	public void testMachine4() {
		TuringMachine tm = new TuringMachine();
		Parser parser = new Parser();
		File file = new File("maquinas/machine4.mt");

		boolean error = true;

		try {
			error = parser.readFile(file, tm);
		} catch (IOException e) {
			System.err.println("Error al abrir el archivo solicitado!");
		}
		
		assertFalse(error);
		
		if (error)
			return;
		
		tm.execute();

		String tape = "";
		for (int i = tm.getMinPosition(); i <= tm.getMaxPosition(); i++) {
			tape += tm.getTape().get(i);
		}

		assertTrue(tape.equals("210001"));
	}
	
	@Test
	public void testEjemplo() {
		TuringMachine tm = new TuringMachine();
		Parser parser = new Parser();
		File file = new File("maquinas/ejemplo.mt");

		boolean error = true;

		try {
			error = parser.readFile(file, tm);
		} catch (IOException e) {
			System.err.println("Error al abrir el archivo solicitado!");
		}
		
		assertFalse(error);
		
		if (error)
			return;
		
		tm.getTape().put(0, 0);
		tm.getTape().put(1, 1);
		tm.getTape().put(2, 2);

		tm.execute();

		String tape = "";
		for (int i = tm.getMinPosition(); i <= tm.getMaxPosition(); i++) {
			tape += tm.getTape().get(i);
		}

		assertTrue(tape.equals("2112000"));
	}
	
}
